package com.stone.serverless.sdk.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.databind.*;

import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

/**
 * @Description: TODO
 * @Author: MECHREVO
 * @Date: 2021/6/15 18:31
 * @Version: 1.0.0
 */
public class JsonUtil {

    /**
     * 日期格式
     */
    public static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd HH:mm:ss";
    /**
     * 序列化与反序列化的Mapper
     */
    private static ObjectMapper objectMapper;

    static {
        //在获取不到就自定义
        if (ObjectUtil.isNull(objectMapper)) {
            objectMapper = new ObjectMapper();
            objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
            objectMapper.setDateFormat(new SimpleDateFormat(DATE_FORMAT_PATTERN));
            objectMapper.setTimeZone(TimeZone.getDefault());
            objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
            objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
            objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX, false);
            objectMapper.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
            objectMapper.configure(JsonReadFeature.ALLOW_SINGLE_QUOTES.mappedFeature(), true);
            objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        }

    }


    /**
     * 转成字符串
     *
     * @param source
     * @return
     */
    public static String toStr(Object source) throws JsonProcessingException {
        return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(source);
    }

    /**
     * 获取一个javaType
     *
     * @param type
     * @return
     */
    public static JavaType getJavaType(Type type) {
        return objectMapper.getTypeFactory().constructType(type);
    }

    /**
     * 转换成一个List
     *
     * @param json
     * @param javaType
     * @return
     */
    public static <T> List<T> toList(String json, JavaType javaType) throws JsonProcessingException {
        return objectMapper.readValue(json, objectMapper.getTypeFactory().constructParametricType(List.class, javaType));
    }

    /**
     * 转换成一个List
     *
     * @param json
     * @param ct
     * @return
     */
    public static <T> List<T> toList(String json, Class<T> ct) throws JsonProcessingException {
        return objectMapper.readValue(json, objectMapper.getTypeFactory().constructParametricType(List.class, ct));
    }

    /**
     * 转换成一个List
     *
     * @param json
     * @return
     */
    public static <T> List<T> toList(JsonNode json) {
        return objectMapper.convertValue(json, List.class);
    }

    /**
     * 转换成一个Map
     *
     * @param json
     * @param p1
     * @param p2
     * @return
     */
    public static <T, R> Map<T, R> toMap(String json, JavaType p1, JavaType p2) throws JsonProcessingException {
        return objectMapper.readValue(json, objectMapper.getTypeFactory().constructParametricType(Map.class, p1, p2));
    }

    /**
     * 转换成一个Map
     *
     * @param json
     * @param p1
     * @param p2
     * @return
     */
    public static <T, R> Map<T, R> toMap(String json, Class p1, Class p2) throws JsonProcessingException {
        return objectMapper.readValue(json, objectMapper.getTypeFactory().constructParametricType(Map.class, p1, p2));
    }

    /**
     * 转换成一个Map
     *
     * @param jsonNode
     * @return
     */
    public static <T, R> Map<T, R> toMap(JsonNode jsonNode) {
        return objectMapper.convertValue(jsonNode, Map.class);
    }

    /**
     * 转换成一个bean
     *
     * @param json
     * @param p1
     * @return
     */
    public static <T> T toBean(String json, JavaType p1) throws JsonProcessingException {
        return objectMapper.readValue(json, p1);
    }

    /**
     * 转换成一个bean
     *
     * @param json
     * @param p1
     * @return
     */
    public static <T> T toBean(Object json, JavaType p1) {
        return objectMapper.convertValue(json, p1);
    }


    /**
     * 转换成一个bean
     *
     * @param json
     * @param p1
     * @return
     */
    public static <T> T toBean(Object json, Class p1) {
        return objectMapper.convertValue(json, getJavaType(p1));
    }

    /**
     * 是否是一个json字符串
     *
     * @param st
     * @return
     */
    public static JsonNode isJsonStr(String st) {
        if (st == null) {
            return null;
        }
        if (!JSONUtil.isJson(st)) {
            return null;
        }
        try {
            return objectMapper.readTree(st);
        } catch (JsonProcessingException e) {
            return null;
        }
    }

    public static ObjectMapper objectMapper() {
        return objectMapper;
    }
}
